﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;

using ABCat.Core;
using ABCat.Core.Plugins;
using ABCat.Shared;
using ABCat.Shared.Properties;
using ABCat.UI.WPF.UI;

namespace ABCat.UI.WPF.Models
{
	public sealed class ConfigViewModel : INotifyPropertyChanged
	{
		#region + Events +

		public event PropertyChangedEventHandler PropertyChanged;
		public event EventHandler Saved;

		#endregion
		#region + Fields +

		private readonly Context _context;
		private readonly ObservableCollection<Config> _parameters = new ObservableCollection<Config>();
		private readonly DelegateCommand _saveCommand;

		private Config _currentConfig;
		private Config _selectedItem;

		#endregion
		#region + Properties +

		public ObservableCollection<Config> Configs
		{
			get { return _parameters; }
		}

		public Config CurrentConfig
		{
			get { return _currentConfig; }
			set
			{
				if (Equals(value, _currentConfig)) return;
				_currentConfig = value;
				OnPropertyChanged();
			}
		}

		public DelegateCommand SaveCommand
		{
			get
			{
				return _saveCommand;
			}
		}

		public Config SelectedItem
		{
			get { return _selectedItem; }
			set
			{
				if (Equals(value, _selectedItem)) return;
				_selectedItem = value;
				OnPropertyChanged();
			}
		}

		#endregion
		#region + Ctor +

		public ConfigViewModel([NotNull] Context context)
		{
			_context = context;
			_saveCommand = new DelegateCommand((obj) =>
			{
				foreach (var pluginConfig in Configs)
				{
					pluginConfig.Check(true);
					pluginConfig.Save();
				}
				var targetWindow = TargetWindow;
				if (targetWindow != null) targetWindow.Close();
			}, (obj) => Configs.Any(item => item.IsChanged));

			var mainConfig = Config.Load<MainConfig>(context);
			mainConfig.Check(false);
			Configs.Add(mainConfig);

			foreach (var configCreatorAttribute in context.PluginsFactory.GetConfigAttributes())
			{
				var config = Config.Load(context, configCreatorAttribute);
				config.Check(false);
				Configs.Add(config);
			}

			SelectedItem = mainConfig;
		}

		public Window TargetWindow { get; set; }

		#endregion
		#region + Logic +

		public static void ShowConfigWindow(Context context, Config targetConfigs)
		{
			var configWindow = new ConfigEditorWindow();
			var cvm = new ConfigViewModel(context);
			configWindow.DataContext = cvm;
			cvm.TargetWindow = configWindow;
			cvm.Saved += cvm_Saved;
			configWindow.ShowDialog();
		}

		static void cvm_Saved(object sender, EventArgs e)
		{
		}

		[NotifyPropertyChangedInvocator]
		private void OnPropertyChanged([CallerMemberName] string propertyName = null)
		{
			PropertyChangedEventHandler handler = PropertyChanged;
			if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
		}

		#endregion
	}
}